﻿// ———————————————————————–
// <copyright file="CoreRoutingService.cs" company="The MITRE Corporation">
//    Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//    Licensed under the Apache License, Version 2.0 (the "License");
//    you may not use this file except in compliance with the License.
//    You may obtain a copy of the License at
//    http://www.apache.org/licenses/LICENSE-2.0
//    Unless required by applicable law or agreed to in writing, software
//    distributed under the License is distributed on an "AS IS" BASIS,
//    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//    See the License for the specific language governing permissions and
//    limitations under the License.
// </copyright>
// ———————————————————————–
/////////////////////////////////////////////////////////////////////////////////////////////////
// CoreRoutingService.cs - "Creates And Configures The Core Routing Service."
// Project: "ICNETSOA"- "ICNETCoreRouter"
//
// Language:    C#, .NET 4.0
// Platform:    Windows 7, VS 2010
// Author:      Don McGarry The MITRE Corporation
/////////////////////////////////////////////////////////////////////////////////////////////////

// Copyright (c) 2010 The MITRE Corporation. All rights reserved.
//
// NOTICE
// This software was produced for the U. S. Government
// under Contract No. FA8721-09-C-0001, and is
// subject to the Rights in Noncommercial Computer Software
// and Noncommercial Computer Software Documentation Clause
// (DFARS) 252.227-7014 (JUN 1995)
                
using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.ServiceModel.Routing;
using System.ServiceProcess;
using ICNETServices;

namespace ICNETCoreRouter
{
  /// <summary>
  /// Methods for creating the core routing service
  /// </summary>
  public partial class CoreRoutingService : ServiceBase
  {
    /// <summary>
    /// The service that runs the core router
    /// </summary>
    private ServiceHost routingHost = null;
    #region Public Methods

    /// <summary>
    /// Initializes a new instance of the CoreRoutingService class.
    /// </summary>
    public CoreRoutingService()
    {
      ServiceName = "IC.NET Core Router";
    }

    /// <summary>
    /// Starts the service.
    /// </summary>
    public static void Main()
    {
      ServiceBase.Run(new CoreRoutingService());
    }

    /// <summary>
    /// Handles known errors. 
    /// </summary>
    /// <param name="sender">The object that contains the fault.</param>
    /// <param name="e">The event that caused the fault</param>
    public void Fault(object sender, EventArgs e)
    {
      ////MessageBox.Show("Fault Occured At: " + DateTime.Now.ToString());
    }

    /// <summary>
    /// Handles unknown errors.
    /// </summary>
    /// <param name="sender">The object that contains the fault.</param>
    /// <param name="e">The message that cannot be associated with callback optoins</param>
    public void Unknown(object sender, UnknownMessageReceivedEventArgs e)
    {
      ////MessageBox.Show("Unknown Occured At: " + DateTime.Now.ToString());
    }
#endregion
    #region Protected Methods

    /// <summary>
    /// Starts up the core routee and configures the end points.
    /// </summary>
    /// <param name="args">The initial arguments</param>
    protected override void OnStart(string[] args)
    {
      if (this.routingHost != null)
      {
        this.routingHost.Close();
      }

      this.routingHost = new ServiceHost(typeof(RoutingService));
      this.ConfigureEndPoints();
      this.routingHost.Open();
    }

    /// <summary>
    /// Closes the router.
    /// </summary>
    protected override void OnStop()
    {
      if (this.routingHost != null)
      {
        this.routingHost.Close();
        this.routingHost = null;
      }
    }
    #endregion
    #region Private Methods 
    
    /// <summary>
    /// Configures the locations of all of the services that the router needs to run. 
    /// </summary>
    private void ConfigureEndPoints()
    {
      string routerAddress = "net.msmq://localhost/private/routingservice/incomingedxl";
      string exceptionServiceAddress = "net.msmq://localhost/private/exceptionservice/exception.svc";
      string distributionElementPorcessingAddress = "net.msmq://localhost/private/deprocessingservice/deprocessing.svc";
      string keywordRoutingAddress = "net.msmq://localhost/private/keywordroutingservice/keywordrouting.svc";
      ////string GeoRSSProcessingAddress = "net.msmq://localhost/private/exposureprocessingservice/exposureprocessing.svc";
      string federationProccessingAddress = "net.msmq://localhost/private/federationservice/federation.svc";
      string deadLetterAddress = "net.msmq://localhost/private/deadletterservice/deadletter.svc";

      System.ServiceModel.Channels.Binding msmqBinding = new NetMsmqBinding("NetMsMQ");

      this.routingHost.AddServiceEndpoint(typeof(ISimplexDatagramRouter), msmqBinding, routerAddress);

      ContractDescription contract = ContractDescription.GetContract(typeof(ISimplexDatagramRouter));
      ServiceEndpoint distributionElementProc = new ServiceEndpoint(contract, msmqBinding, new EndpointAddress(distributionElementPorcessingAddress));
      ServiceEndpoint keyRoute = new ServiceEndpoint(contract, msmqBinding, new EndpointAddress(keywordRoutingAddress));
      ////ServiceEndpoint GeoRSS = new ServiceEndpoint(contract, msmqBinding, new EndpointAddress(GeoRSSProcessingAddress));
      ServiceEndpoint excep = new ServiceEndpoint(contract, msmqBinding, new EndpointAddress(exceptionServiceAddress));
      ServiceEndpoint federation = new ServiceEndpoint(contract, msmqBinding, new EndpointAddress(federationProccessingAddress));
      ServiceEndpoint deadLetter = new ServiceEndpoint(contract, msmqBinding, new EndpointAddress(deadLetterAddress));

      RoutingConfiguration routerconfig = new RoutingConfiguration();
      List<ServiceEndpoint> distributionElementClients = new List<ServiceEndpoint>();
      distributionElementClients.Add(distributionElementProc);
      List<ServiceEndpoint> fedClients = new List<ServiceEndpoint>();
      fedClients.Add(federation);
      List<ServiceEndpoint> keywordClients = new List<ServiceEndpoint>();
      keywordClients.Add(keyRoute);
      ////List<ServiceEndpoint> GeoRSSClients = new List<ServiceEndpoint>();
      ////GeoRSSClients.Add(GeoRSS);
      List<ServiceEndpoint> exceptionClients = new List<ServiceEndpoint>();
      exceptionClients.Add(excep);
      List<ServiceEndpoint> deadLetterClients = new List<ServiceEndpoint>();
      deadLetterClients.Add(deadLetter);

      ValueListMessageFilter deprocessingfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETServicesURI + ";" + ICNETSOAConstants.KeywordRoutingServiceNamespace);
      ValueListMessageFilter federationfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETServicesURI + ";" + ICNETSOAConstants.DEPostServiceNamespace);
      ValueListMessageFilter deprocessingfedfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETfedURI + ";" + ICNETSOAConstants.DEFedServiceNamespace);
      ValueListMessageFilter federationfedfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETfedURI + ";" + ICNETSOAConstants.DEFedServiceNamespace);
      ValueListMessageFilter pollingfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETServicesURI + ";" + ICNETSOAConstants.PollingServiceNamespace);
      ValueListMessageFilter keywordroutingfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETServicesURI + ";" + ICNETSOAConstants.DEPostServiceNamespace);
      ////ValueListMessageFilter georssfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETServicesURI + ";" + ICNETSOAConstants.KeywordRoutingServiceNamespace);
      ValueListMessageFilter excepprocessingfilter = new ValueListMessageFilter("senderRole;" + ICNETSOAConstants.ICNETServicesURI + ";" + ICNETSOAConstants.ExceptionServiceNamespace);

      routerconfig.FilterTable.Add(pollingfilter, keywordClients, 1);
      routerconfig.FilterTable.Add(federationfilter, fedClients, 1);
      routerconfig.FilterTable.Add(federationfedfilter, fedClients, 1);
      routerconfig.FilterTable.Add(deprocessingfedfilter, keywordClients, 1);
      routerconfig.FilterTable.Add(keywordroutingfilter, keywordClients, 1);
      ////routerconfig.FilterTable.Add(georssfilter, GeoRSSClients, 1);
      routerconfig.FilterTable.Add(deprocessingfilter, distributionElementClients, 1);
      routerconfig.FilterTable.Add(excepprocessingfilter, exceptionClients, 1);
      routerconfig.FilterTable.Add(new MatchAllMessageFilter(), deadLetterClients, 0);
      routerconfig.SoapProcessingEnabled = false;
      routerconfig.RouteOnHeadersOnly = false;
      this.routingHost.Description.Behaviors.Add(new RoutingBehavior(routerconfig));
      this.routingHost.Faulted += new EventHandler(this.Fault);
      this.routingHost.UnknownMessageReceived += new EventHandler<UnknownMessageReceivedEventArgs>(this.Unknown);
    }
    #endregion
  }
}
